using System;
using System.Collections.Generic;
using System.IO;
using System.Security;
using System.Text;
using System.Threading;
using System.Transactions;
using Oracle.ManagedDataAccess.Client;
using OracleInternal.Common;
using OracleInternal.MTS;
using OracleInternal.Network;
using OracleInternal.ServiceObjects;
using OracleInternal.Sharding;

namespace OracleInternal.ConnectionPool
{
	internal static class OracleConnectionDispenser<PM, CP, PR> where PM : PoolManager<PM, CP, PR>, new()where CP : Pool<PM, CP, PR>, new()where PR : PoolResource<PM, CP, PR>, new()
	{
		public static SyncDictionary<ConnectionPoolId, PM> m_htPM;

		public static SyncQueueList<PM> m_listPM;

		internal static SyncQueueList<string> m_listDataSources;

		internal static object m_syncObjForGetDataSources;

		internal static SyncDictionary<string, ManualResetEventSlim> m_chunkUpEvents;

		internal static FileSystemWatcher s_sepsFileWatcher;

		internal static object s_sepsFileWatcherCreationLock;

		internal static bool s_bSEPSFileWatcherCreated;

		internal static ChunkUpEvent m_sChunkUpEvents;

		internal static object s_shardLockObj;

		static OracleConnectionDispenser()
		{
			m_syncObjForGetDataSources = new object();
			s_sepsFileWatcherCreationLock = new object();
			s_bSEPSFileWatcherCreated = false;
			s_shardLockObj = new object();
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.cctor);
			}
			try
			{
				m_htPM = new SyncDictionary<ConnectionPoolId, PM>();
				m_listPM = new SyncQueueList<PM>();
				m_listDataSources = new SyncQueueList<string>();
				m_sChunkUpEvents = new ChunkUpEvent();
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268437504, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.cctor, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2560, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.cctor);
				}
			}
		}

		internal static void CreateSEPSFileWatcher(string walletPath, string walletFile)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.CreateSEPSFileWatcher);
			}
			try
			{
				if (s_bSEPSFileWatcherCreated)
				{
					return;
				}
				lock (s_sepsFileWatcherCreationLock)
				{
					if (!s_bSEPSFileWatcherCreated)
					{
						Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.CreateSEPSFileWatcher, "Creating FileWatcher for WalletPath:<{0}>, WalletFile:<{1}>", walletPath, walletFile);
						s_sepsFileWatcher = new FileSystemWatcher();
						s_sepsFileWatcher.Filter = walletFile;
						FileSystemEventHandler value = SEPSFileChangedEvent;
						s_sepsFileWatcher.Changed += value;
						s_sepsFileWatcher.Created += value;
						s_sepsFileWatcher.Deleted += value;
						s_sepsFileWatcher.Renamed += SEPSFileRenamedEvent;
						s_sepsFileWatcher.Path = walletPath;
						s_sepsFileWatcher.EnableRaisingEvents = true;
						s_bSEPSFileWatcherCreated = true;
					}
				}
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2560, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.CreateSEPSFileWatcher);
				}
			}
		}

		internal static void SEPSFileRenamedEvent(object source, RenamedEventArgs e)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.SEPSFileRenamedEvent);
			}
			try
			{
				Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.SEPSFileRenamedEvent, "TID:{0} => File <{1}> has been {2} at Time:{3}!", Thread.CurrentThread.ManagedThreadId.ToString(), e.FullPath, e.ChangeType.ToString(), DateTime.Now.ToString());
				ProcessSEPSFileChangeEvent();
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2560, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.SEPSFileRenamedEvent);
				}
			}
		}

		internal static void SEPSFileChangedEvent(object sender, FileSystemEventArgs e)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.SEPSFileChangedEvent);
			}
			Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.SEPSFileChangedEvent, "TID:{0} => File <{1}> has been {2} at Time:{3}!", Thread.CurrentThread.ManagedThreadId.ToString(), e.FullPath, e.ChangeType.ToString(), DateTime.Now.ToString());
			ProcessSEPSFileChangeEvent();
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2560, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.SEPSFileChangedEvent);
			}
		}

		internal static void ProcessSEPSFileChangeEvent()
		{
			List<PM> list = m_listPM.GetList();
			for (int i = 0; i < list.Count; i++)
			{
				PM val = list[i];
				if (!val.m_bUsingSEPSCredentials)
				{
					continue;
				}
				try
				{
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.ProcessSEPSFileChangeEvent, "ProcessSEPSFileChangeEvent => Querying Data Source:" + val.m_cs.m_dataSource);
					string U;
					SecureString PW;
					try
					{
						OracleCommunication.GetSEPSUserIDandPW(val.m_cs.m_dataSource, out U, out PW, out var _, out var _);
					}
					catch
					{
						Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.ProcessSEPSFileChangeEvent, "ProcessSEPSFileChangeEvent => Exception raised from OracleCommunication.GetSEPSUserIDandPW for DataSource: " + val.m_cs.m_dataSource);
						m_listPM.GetList();
						for (int j = 0; j < list.Count; j++)
						{
							PM val2 = list[i];
							if (val2.m_bUsingSEPSCredentials)
							{
								val2.m_bSEPSCredentialsFetched = false;
								val2.ClearAllPools(null);
							}
						}
						return;
					}
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.ProcessSEPSFileChangeEvent, "ProcessSEPSFileChangeEvent => Got Credentials from Client Wallet");
					bool flag = false;
					if (val.m_bSEPSForProxyCredentials)
					{
						if (U != val.m_cs.m_sepsProxyUserId || PW != val.m_cs.m_sepsSecuredProxyPassword)
						{
							flag = true;
						}
					}
					else if (U != val.m_cs.m_sepsUserId || PW != val.m_cs.m_sepsSecuredPassword)
					{
						flag = true;
					}
					if (flag)
					{
						Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.ProcessSEPSFileChangeEvent, "ProcessSEPSFileChangeEvent => Credentials DOES NOT Match: Calling ClearPool");
						val.ClearAllPools(null);
						if (val.m_bSEPSForProxyCredentials)
						{
							val.m_cs.m_sepsProxyUserId = U;
							val.m_cs.m_sepsSecuredProxyPassword = PW;
						}
						else
						{
							val.m_cs.m_sepsUserId = U;
							val.m_cs.m_sepsSecuredPassword = PW;
						}
						val.m_bSEPSCredentialsFetched = true;
					}
				}
				catch (Exception ex)
				{
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.ProcessSEPSFileChangeEvent, "ProcessSEPSFileChangeEvent => Exception while processing: {0}", ex.ToString());
				}
			}
		}

		internal static string Dump()
		{
			StringBuilder stringBuilder = new StringBuilder();
			try
			{
				stringBuilder.AppendLine("(DUMP)");
				foreach (ConnectionPoolId key in m_htPM.GetKeys())
				{
					PM val = m_htPM[key];
					if (val == null)
					{
						continue;
					}
					stringBuilder.AppendLine("(CP) =================================");
					stringBuilder.AppendLine("(CP) " + key.m_pwdLessconnString);
					stringBuilder.AppendLine("(CP) pmid=");
					stringBuilder.Append(val.m_id);
					stringBuilder.AppendLine("(CP) =================================");
					foreach (CP item in val.m_pmListCP.GetList())
					{
						stringBuilder.AppendLine("(CP) " + item.m_serviceName + " , " + item.m_instanceName + ":");
						List<PR> list = item.m_cpListPR.GetList();
						stringBuilder.Append("(CP)   list  (count:" + list.Count + ") : ");
						foreach (PR item2 in list)
						{
							if (item2.Dump())
							{
								if (item2.m_sessionType != SessionType.Two_Session_Proxy)
								{
									stringBuilder.AppendLine("(" + item2.m_endUserSessionId + ":" + item2.m_endUserSerialNum + ":" + item2.m_bCheckedOutByApp.ToString().Substring(0, 1) + ":" + item2.m_bCheckedOutByDTC.ToString().Substring(0, 1) + ":" + item2.m_bPutCompleted.ToString().Substring(0, 1) + ":" + item2.m_bTxnCtxPrimaryCon.ToString().Substring(0, 1) + ":" + ((item2.m_mtsTxnCtx != null) ? item2.m_mtsTxnCtx.m_txnType.ToString().Substring(0, 1) : "N") + ":" + item2.ServiceName + ":" + item2.EditionName + ":" + item2.m_instanceName + ")");
								}
								else
								{
									stringBuilder.AppendLine("(" + item2.m_endUserSessionId + "," + item2.m_pxyUserSessionId + item2.m_bCheckedOutByApp.ToString().Substring(0, 1) + ":" + item2.m_bCheckedOutByDTC.ToString().Substring(0, 1) + ":" + item2.m_bPutCompleted.ToString().Substring(0, 1) + ":" + item2.m_bTxnCtxPrimaryCon.ToString().Substring(0, 1) + ":" + ((item2.m_mtsTxnCtx != null) ? item2.m_mtsTxnCtx.m_txnType.ToString().Substring(0, 1) : "N") + ":" + item2.ServiceName + ":" + item2.EditionName + ":" + item2.m_instanceName + ")");
								}
							}
							else
							{
								stringBuilder.Append("(" + item2.m_endUserSessionId + ":CLOSED)");
							}
						}
						stringBuilder.AppendLine();
						list = item.m_cpQueuePR.GetList();
						stringBuilder.Append("(CP)   queue (count:" + list.Count + ") : ");
						foreach (PR item3 in list)
						{
							if (item3.Dump())
							{
								if (item3.m_sessionType != SessionType.Two_Session_Proxy)
								{
									stringBuilder.Append("(" + item3.m_endUserSessionId + ":" + item3.m_endUserSerialNum + ":" + item3.m_bCheckedOutByApp.ToString().Substring(0, 1) + ":" + item3.m_bCheckedOutByDTC.ToString().Substring(0, 1) + ":" + item3.m_bPutCompleted.ToString().Substring(0, 1) + ":" + item3.m_bTxnCtxPrimaryCon.ToString().Substring(0, 1) + ":" + ((item3.m_mtsTxnCtx != null) ? item3.m_mtsTxnCtx.m_txnType.ToString().Substring(0, 1) : "N") + ":" + item3.ServiceName + ":" + item3.EditionName + ":" + item3.m_instanceName + ")");
								}
								else
								{
									stringBuilder.Append("(" + item3.m_endUserSessionId + "," + item3.m_pxyUserSessionId + item3.m_bCheckedOutByApp.ToString().Substring(0, 1) + ":" + item3.m_bCheckedOutByDTC.ToString().Substring(0, 1) + ":" + item3.m_bPutCompleted.ToString().Substring(0, 1) + ":" + item3.m_bTxnCtxPrimaryCon.ToString().Substring(0, 1) + ":" + ((item3.m_mtsTxnCtx != null) ? item3.m_mtsTxnCtx.m_txnType.ToString().Substring(0, 1) : "N") + ":" + item3.ServiceName + ":" + item3.EditionName + ":" + item3.m_instanceName + ")");
								}
							}
							else
							{
								stringBuilder.Append("(" + item3.m_endUserSessionId + ":CLOSED)");
							}
						}
						stringBuilder.AppendLine();
					}
					if (val.m_dictDictTxnCtx == null)
					{
						continue;
					}
					foreach (string key2 in val.m_dictDictTxnCtx.GetKeys())
					{
						List<string> keys = val.m_dictDictTxnCtx[key2].GetKeys();
						for (int i = 0; i < keys.Count; i++)
						{
							int num = 0;
							TransactionContext<PM, CP, PR> transactionContext = val.m_dictDictTxnCtx[key2][keys[i]];
							if (transactionContext == null)
							{
								continue;
							}
							stringBuilder.Append("(CP) mts (" + key2 + ") : (" + keys[i] + ")");
							if (transactionContext.m_enlistedPRList != null)
							{
								for (int j = 0; j < 33; j++)
								{
									PR val2 = transactionContext.m_enlistedPRList[j];
									if (val2 == null)
									{
										continue;
									}
									num++;
									if (val2.Dump())
									{
										if (val2.m_sessionType != SessionType.Two_Session_Proxy)
										{
											stringBuilder.Append(string.Format("[{0}:({1}:{2});{3};{4};{5};{6};{7};{8};{9};{10}]", j, val2.m_endUserSessionId, val2.m_endUserSerialNum, val2.m_bCheckedOutByApp.ToString().Substring(0, 1), val2.m_bCheckedOutByDTC.ToString().Substring(0, 1), val2.m_bPutCompleted.ToString().Substring(0, 1), val2.m_bTxnCtxPrimaryCon.ToString().Substring(0, 1), (val2.m_mtsTxnCtx != null) ? val2.m_mtsTxnCtx.m_txnType.ToString().Substring(0, 1) : "N", val2.ServiceName, val2.EditionName, val2.m_instanceName));
										}
										else
										{
											stringBuilder.Append("(" + val2.m_endUserSessionId + "," + val2.m_pxyUserSessionId + ")");
										}
									}
									else
									{
										stringBuilder.Append("(" + val2.m_endUserSessionId + ":CLOSED)");
									}
								}
								stringBuilder.Append("(count:" + num + ")");
							}
							else
							{
								stringBuilder.Append("(null list!!!)");
							}
							stringBuilder.AppendLine();
						}
					}
				}
			}
			catch
			{
			}
			return stringBuilder.ToString();
		}

		internal static string Dump(string txnid)
		{
			StringBuilder stringBuilder = new StringBuilder();
			try
			{
				stringBuilder.Append("(DUMP)");
				List<ConnectionPoolId> keys = m_htPM.GetKeys();
				TransactionContext<PM, CP, PR> transactionContext = null;
				foreach (ConnectionPoolId item in keys)
				{
					transactionContext = null;
					PM val = m_htPM[item];
					if (val == null || val.m_dictDictTxnCtx == null || !val.m_dictDictTxnCtx.ContainsKey(txnid))
					{
						continue;
					}
					foreach (string key in val.m_dictDictTxnCtx[txnid].GetKeys())
					{
						transactionContext = val.m_dictDictTxnCtx[txnid][key];
						if (transactionContext == null)
						{
							continue;
						}
						stringBuilder.Append("(txnid=" + txnid + ") ");
						stringBuilder.Append("(service name=" + key + ") ");
						stringBuilder.Append("(pmid=" + val.m_id + ")[");
						if (transactionContext.m_enlistedPRList != null)
						{
							int num = 0;
							for (int i = 0; i < 33; i++)
							{
								PR val2 = transactionContext.m_enlistedPRList[i];
								if (val2 == null)
								{
									continue;
								}
								num++;
								if (val2.Dump())
								{
									if (val2.m_sessionType != SessionType.Two_Session_Proxy)
									{
										stringBuilder.Append(string.Format("[{0}:({1}:{2});{3};{4};{5};{6};{7};{8};{9};{10}]", i, val2.m_endUserSessionId, val2.m_endUserSerialNum, val2.m_bCheckedOutByApp.ToString().Substring(0, 1), val2.m_bCheckedOutByDTC.ToString().Substring(0, 1), val2.m_bPutCompleted.ToString().Substring(0, 1), val2.m_bTxnCtxPrimaryCon.ToString().Substring(0, 1), (val2.m_mtsTxnCtx != null) ? val2.m_mtsTxnCtx.m_txnType.ToString().Substring(0, 1) : "N", val2.ServiceName, val2.EditionName, val2.m_instanceName + " (pr.m_pm.GetHashCode()      : " + val.GetHashCode() + ") (pr.m_pm.m_cs.GetHashCode() : " + val.m_cs.GetHashCode() + ") (pr.m_pm.m_cs.m_userId      : " + val.m_cs.m_userId + ") (pr.m_pm.m_cs.m_proxyUserId : " + val.m_cs.m_proxyUserId + ") (pr.m_cs.GetHashCode()      : " + val.m_cs.GetHashCode() + ") (pr.m_cs.m_userId           : " + val.m_cs.m_userId + ") (pr.m_cs.m_proxyUserId      : " + val.m_cs.m_proxyUserId + ") "));
									}
									else
									{
										stringBuilder.Append("(" + val2.m_endUserSessionId + "," + val2.m_pxyUserSessionId + ")");
									}
								}
								else
								{
									stringBuilder.Append("(" + val2.m_endUserSessionId + ":CLOSED)");
								}
							}
							stringBuilder.Append("(count:" + num + ")");
						}
						else
						{
							stringBuilder.Append("(null list!!!)");
						}
						stringBuilder.Append("] ");
					}
				}
			}
			catch
			{
			}
			return stringBuilder.ToString();
		}

		internal static PM GetPM(ConnectionString cs, OracleConnection con, PM conPM, ConnectionString pmCS, SecureString securedPassword, SecureString securedProxyPassword, out bool bAuthenticated, out bool newPM)
		{
			PM val = null;
			bAuthenticated = false;
			newPM = false;
			if (conPM == null)
			{
				if (cs.m_conPoolKey != null)
				{
					val = m_htPM[cs.m_conPoolKey];
				}
				if (val == null)
				{
					lock (m_htPM)
					{
						if (cs.m_conPoolKey != null)
						{
							val = m_htPM[cs.m_conPoolKey];
						}
						if (val == null)
						{
							val = new PM();
							val.Initialize(cs, con);
							m_htPM[cs.m_conPoolKey] = val;
							m_listPM.Add(val);
							newPM = true;
							bAuthenticated = true;
						}
					}
				}
				if (val != null && !newPM)
				{
					if ((val.m_cs.m_orclCredential != null && val.m_cs.m_orclCredential.m_bProxyPasswordSet) || val.m_cs.m_bProxyPasswordSet)
					{
						bAuthenticated = ConnectionString.SecureStringsEqual(val.m_cs.m_securedProxyPassword, cs.m_securedProxyPassword);
					}
					else
					{
						bAuthenticated = ConnectionString.SecureStringsEqual(val.m_cs.m_securedPassword, cs.m_securedPassword);
					}
				}
			}
			else if (securedPassword == null && securedProxyPassword == null)
			{
				val = conPM;
				bAuthenticated = true;
			}
			else
			{
				val = conPM;
				bAuthenticated = true;
				if (pmCS != val.m_cs)
				{
					if (securedPassword != null)
					{
						bAuthenticated = ConnectionString.SecureStringsEqual(val.m_cs.m_securedPassword, securedPassword);
					}
					if (bAuthenticated && securedProxyPassword != null)
					{
						bAuthenticated = ConnectionString.SecureStringsEqual(val.m_cs.m_securedProxyPassword, securedProxyPassword);
					}
				}
			}
			bool flag = false;
			if (con != null)
			{
				flag = con.m_shardKey != null || con.m_shardGroupKey != null;
			}
			if (val.m_cs.m_pooling && flag)
			{
				string[] readOnlyInstances = null;
				con.m_shardingChunk = null;
				if (!val.m_bReadOnlyChunkOK.HasValue)
				{
					con.m_shardingInstances = null;
				}
				else if (val.m_bReadOnlyChunkOK == true)
				{
					con.m_shardingInstances = val.GetShardInstancesEx(con, ref con.m_shardingChunk, ref readOnlyInstances, ref con.m_shardingInstanceInfos);
				}
				else
				{
					con.m_shardingInstances = val.GetShardInstancesEx(con, ref con.m_shardingChunk, ref readOnlyInstances, ref con.m_shardingInstanceInfos);
					string text = null;
					if (con.m_shardingInstances != null && con.m_shardingInstances.Length != 0 && !string.IsNullOrEmpty(con.m_shardingInstances[0]))
					{
						text = con.m_shardingInstances[0];
					}
					else if (readOnlyInstances != null && readOnlyInstances.Length != 0 && !string.IsNullOrEmpty(readOnlyInstances[0]))
					{
						text = readOnlyInstances[0];
					}
					ManualResetEventSlim manualResetEventSlim = null;
					if (text != null)
					{
						manualResetEventSlim = m_sChunkUpEvents.GetEvent(val.m_databaseName, text, con.m_shardingChunk);
					}
					if (manualResetEventSlim != null)
					{
						int result = 120;
						if (con != null && con.m_oracleConnectionImpl != null && con.m_oracleConnectionImpl.m_pm != null && !string.IsNullOrEmpty(con.m_oracleConnectionImpl.m_pm.m_chunkMigrationConTimeout))
						{
							int.TryParse(con.m_oracleConnectionImpl.m_pm.m_chunkMigrationConTimeout, out result);
						}
						if (ProviderConfig.m_bTraceLevelPrivate)
						{
							Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.GetPM, string.Format("Sharding:Blocked:WaitAny(max={4}sec) for {0}|{1}|{2}|{3}", val.m_databaseDomainName, val.m_databaseName, text, con.m_shardingChunk, result));
						}
						if (WaitHandle.WaitAny(new WaitHandle[1]
						{
							manualResetEventSlim.WaitHandle
						}, result * 1000) == 258)
						{
							m_sChunkUpEvents.SetAndRemoveEvent(val.m_databaseName, text, con.m_shardingChunk);
							con.m_shardingInstances = val.GetShardInstancesEx(con, ref con.m_shardingChunk, ref readOnlyInstances, ref con.m_shardingInstanceInfos);
							if (ProviderConfig.m_bTraceLevelPrivate)
							{
								Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.GetPM, string.Format("Sharding:UnBlocked:Timeout(max={4}sec) for {0}|{1}|{2}|{3}", val.m_databaseDomainName, val.m_databaseName, text, con.m_shardingChunk, result));
							}
						}
						else
						{
							con.m_shardingInstances = val.GetShardInstancesEx(con, ref con.m_shardingChunk, ref readOnlyInstances, ref con.m_shardingInstanceInfos);
							if (ProviderConfig.m_bTraceLevelPrivate)
							{
								Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.GetPM, $"Sharding:UnBlocked:UpEvent for {val.m_databaseDomainName}|{val.m_databaseName}|{text}|{con.m_shardingChunk}");
							}
						}
					}
				}
			}
			return val;
		}

		internal static PR Get(ConnectionString cs, PM conPM, ConnectionString pmCS, SecureString securedPassword, SecureString securedProxyPassword, OracleConnection connRefForCriteria)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.Get);
			}
			PR val = null;
			try
			{
				if (cs.m_conPoolKey == null)
				{
					OracleCredential orclCredential = null;
					if (connRefForCriteria != null)
					{
						orclCredential = connRefForCriteria.m_orclCredential;
					}
					cs.m_conPoolKey = new ConnectionPoolId(cs.m_pmId, orclCredential);
				}
				PM val2 = null;
				bool newPM = false;
				bool bAuthenticated = false;
				val2 = GetPM(cs, connRefForCriteria, conPM, pmCS, securedPassword, securedProxyPassword, out bAuthenticated, out newPM);
				try
				{
					if (bAuthenticated && connRefForCriteria.m_secureNewPassword == null)
					{
						ConnectionString csWithDiffOrNewPwd = null;
						if ((cs.m_orclCredential != null && cs.m_orclCredential.m_bProxyUserIdSet) || cs.m_bProxyUserIdSet || cs.m_bDBStartup)
						{
							csWithDiffOrNewPwd = cs;
						}
						val = ((!(Transaction.Current != null) || cs.m_enlist != Enlist.True) ? val2.Get(csWithDiffOrNewPwd, bGetForApp: true, connRefForCriteria) : val2.GetEnlisted(csWithDiffOrNewPwd, bGetForApp: true, connRefForCriteria));
					}
					else
					{
						cs = cs.Clone();
						if (securedPassword != null)
						{
							cs.m_securedPassword = securedPassword;
						}
						if (securedProxyPassword != null)
						{
							cs.m_securedProxyPassword = securedProxyPassword;
						}
						val = val2.GetUsingDiffPassword(cs, connRefForCriteria);
						if (val != null)
						{
							val2.ClearAllPools(val);
							ConnectionString.m_conStringPool.Remove(val2.m_cs);
							val2.m_cs = val2.m_cs.Clone();
							if (connRefForCriteria.m_orclCredential != null)
							{
								if (connRefForCriteria.m_secureNewPassword != null)
								{
									connRefForCriteria.m_orclCredential.m_securePassword = connRefForCriteria.m_secureNewPassword;
								}
								else
								{
									connRefForCriteria.m_orclCredential.m_securePassword = cs.m_securedPassword;
								}
							}
							else if (connRefForCriteria.m_secureNewPassword != null)
							{
								val2.m_cs.m_securedPassword = connRefForCriteria.m_secureNewPassword;
							}
							else
							{
								val2.m_cs.m_securedPassword = cs.m_securedPassword;
							}
							val2.m_cs.m_secPxyPwdList.Clear();
							val2.m_cs.m_secPwdList.Clear();
							ConnectionString.m_conStringPool.Put(val2.m_cs);
						}
					}
					int count = val2.m_pmListPR.Count;
					if (val2.m_cs.m_pooling && val2.m_cs.m_minPoolSize > 1 && count < val2.m_cs.m_minPoolSize && count < val2.m_cs.m_maxPoolSize && val2.m_semPoolPopulation.WaitOne(0))
					{
						if (val2.m_pmListPR.Count < val2.m_cs.m_minPoolSize)
						{
							int num = val2.m_cs.m_minPoolSize - val2.m_pmListPR.Count;
							if (num > 0)
							{
								string connectionClass = null;
								if (connRefForCriteria != null)
								{
									connectionClass = connRefForCriteria.m_criteriaConnCls;
								}
								PoolPopulationOption state = new PoolPopulationOption(num, val2.m_cs.m_minPoolSize, val2.m_semPoolPopulation, ignoreIncrPoolSize: true, connectionClass);
								ThreadPool.QueueUserWorkItem(new WaitCallback(val2.PopulatePoolThreadFunc), state);
							}
							else
							{
								val2.m_semPoolPopulation.Release();
							}
						}
						else
						{
							val2.m_semPoolPopulation.Release();
						}
					}
				}
				catch
				{
					if (newPM)
					{
						ConnectionPoolId conPoolKey = cs.m_conPoolKey;
						if (conPoolKey != null && m_htPM != null)
						{
							m_htPM.Remove(conPoolKey);
						}
						if (val2 != null && m_listPM != null)
						{
							m_listPM.Remove(val2);
						}
						if (val2 != null && m_listDataSources != null)
						{
							m_listDataSources.Remove(val2.m_cs.m_dataSource);
						}
						if (val2 != null && val2.m_cs != null)
						{
							ConnectionString.m_conStringPool.Remove(val2.m_cs);
						}
						if (val2 != null && val2.m_timer != null)
						{
							try
							{
								val2.m_timer.Dispose();
							}
							catch
							{
							}
						}
					}
					throw;
				}
				if (newPM && val.m_cs.m_selfTuning && val.m_cs.m_pooling)
				{
					val2.InitializeSelfTuning();
				}
				if (OraclePool.m_bPerfCounterEnabled && val != null)
				{
					OraclePool op = val.m_cp as OraclePool;
					if (val.m_cs.m_pooling)
					{
						if (OraclePool.m_bPerfSoftConnectsPerSecond)
						{
							OraclePool.PerformanceCounterIncrement(OraclePerfParams.CounterIndex.SoftConnectsPerSecond, val as OracleConnectionImpl, op);
						}
					}
					else if (OraclePool.m_bPerfNumberOfNonPooledConnections)
					{
						OraclePool.PerformanceCounterIncrement(OraclePerfParams.CounterIndex.NumberOfNonPooledConnections, val as OracleConnectionImpl, op);
					}
					if (OraclePool.m_bPerfNumberOfActiveConnections)
					{
						OraclePool.PerformanceCounterIncrement(OraclePerfParams.CounterIndex.NumberOfActiveConnections, val as OracleConnectionImpl, op);
					}
				}
				return val;
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268437504, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.Get, ex);
				throw;
			}
			finally
			{
				if (val != null)
				{
					lock (val)
					{
						val.m_bCheckedOutByApp = true;
					}
				}
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2560, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.Get, Trace.GetCPInfo(val as OracleConnectionImpl, null, null, null));
				}
			}
		}

		internal static void PutFromApp(PR pr, OracleConnection connRefForCriteria)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.PutFromApp, Trace.GetCPInfo(pr as OracleConnectionImpl, null, null, null));
			}
			try
			{
				if (pr == null)
				{
					return;
				}
				lock (pr)
				{
					pr.m_bCheckedOutByApp = false;
				}
				Put(pr, connRefForCriteria);
				if (!OraclePool.m_bPerfCounterEnabled)
				{
					return;
				}
				OraclePool op = pr.m_cp as OraclePool;
				if (pr.m_cs.m_pooling)
				{
					if (OraclePool.m_bPerfNumberOfFreeConnections)
					{
						OraclePool.PerformanceCounterIncrement(OraclePerfParams.CounterIndex.NumberOfFreeConnections, pr as OracleConnectionImpl, op);
					}
					if (OraclePool.m_bPerfSoftDisconnectsPerSecond)
					{
						OraclePool.PerformanceCounterIncrement(OraclePerfParams.CounterIndex.SoftDisconnectsPerSecond, pr as OracleConnectionImpl, op);
					}
				}
				else if (OraclePool.m_bPerfNumberOfNonPooledConnections)
				{
					OraclePool.PerformanceCounterDecrement(OraclePerfParams.CounterIndex.NumberOfNonPooledConnections, pr as OracleConnectionImpl, op);
				}
				if (OraclePool.m_bPerfNumberOfActiveConnections)
				{
					OraclePool.PerformanceCounterDecrement(OraclePerfParams.CounterIndex.NumberOfActiveConnections, pr as OracleConnectionImpl, op);
				}
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268437504, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.PutFromApp, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2560, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.PutFromApp, Trace.GetCPInfo(pr as OracleConnectionImpl, null, null, null));
				}
			}
		}

		internal static void PutFromPSPE(Transaction txn, PR pr)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)6400, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.PutFromPSPE, "Local TxnID = " + txn.TransactionInformation.LocalIdentifier + " using Conn ID = " + pr.m_endUserSessionId + " to DBInst = " + pr.m_instanceName);
			}
			try
			{
				if (pr != null && pr.m_pm != null && pr.m_pm.m_dictDictTxnCtx != null && pr.m_pm.m_dictDictTxnCtx[txn.TransactionInformation.LocalIdentifier] != null && pr.m_pm.m_dictDictTxnCtx[txn.TransactionInformation.LocalIdentifier][pr.ServiceName] != null && pr.m_mtsTxnCtx.m_txnType == MTSTxnType.Distributed)
				{
					pr.m_pm.m_dictDictTxnCtx[txn.TransactionInformation.LocalIdentifier][pr.ServiceName].m_enlistedPRList[0] = null;
				}
				PutFromDTC(pr);
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268437504, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.PutFromPSPE, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)6656, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.PutFromPSPE, "Local TxnID = " + txn.TransactionInformation.LocalIdentifier + " using Conn ID = " + pr.m_endUserSessionId + " to DBInst = " + pr.m_instanceName);
				}
			}
		}

		internal static void PutFromDTC(PR pr)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.PutFromDTC, Trace.GetCPInfo(pr as OracleConnectionImpl, null, null, null));
			}
			try
			{
				if (pr == null)
				{
					return;
				}
				lock (pr)
				{
					if (pr.m_bCheckedOutByDTC)
					{
						pr.m_resPoolRefCount--;
					}
					if (pr.m_resPoolRefCount != 0)
					{
						return;
					}
					pr.m_bCheckedOutByDTC = false;
				}
				Put(pr, null);
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268437504, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.PutFromDTC, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2560, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.PutFromDTC, Trace.GetCPInfo(pr as OracleConnectionImpl, null, null, null));
				}
			}
		}

		private static void Put(PR pr, OracleConnection connRefForCriteria)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.Put, Trace.GetCPInfo(pr as OracleConnectionImpl, null, null, null));
			}
			try
			{
				if (pr.m_mtsTxnCtx != null)
				{
					pr.m_pm.m_criteriaMapper.GetId(pr as OracleConnectionImpl);
					if (pr.m_mtsTxnCtx.m_txnType == MTSTxnType.Local)
					{
						return;
					}
					if (pr.m_mtsTxnCtx != null && pr.m_mtsTxnCtx.m_txnType == MTSTxnType.Distributed)
					{
						lock (pr)
						{
							if (pr.m_mtsTxnCtx != null && pr.m_mtsTxnCtx.m_txnType == MTSTxnType.Distributed)
							{
								if (pr.m_txnCtx == null && pr.m_mtsTxnCtx != null && pr.m_pm.m_dictDictTxnCtx[pr.m_mtsTxnCtx.m_txnLocalID] != null)
								{
									pr.m_txnCtx = pr.m_pm.m_dictDictTxnCtx[pr.m_mtsTxnCtx.m_txnLocalID][pr.ServiceName];
								}
								if (pr.m_txnCtx != null && !pr.m_bCheckedOutByApp && !pr.m_bCheckedOutByDTC && !pr.m_bPutCompleted && pr.m_mtsTxnCtx != null && pr.m_mtsTxnCtx.m_txnType == MTSTxnType.Distributed && !pr.m_bTxnCtxPrimaryCon)
								{
									lock (pr.m_txnCtx)
									{
										if (pr.m_mtsTxnCtx != null && pr.m_mtsTxnCtx.m_txnType == MTSTxnType.Distributed)
										{
											try
											{
												pr.m_mtsTxnCtx.DelistTransaction(pr as OracleConnectionImpl);
											}
											catch
											{
											}
											if (ProviderConfig.m_bTraceLevelPrivate)
											{
												Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.Put, Trace.GetCPInfo(pr as OracleConnectionImpl, null, null, "disp:put:del1"));
											}
										}
										if (pr.m_localTxnId == pr.m_txnCtx.m_localTxnId)
										{
											PR val = null;
											if (pr.m_mtsTxnCtx.m_mtsTxnBranch != null)
											{
												val = pr.m_txnCtx.m_enlistedPRList[pr.m_mtsTxnCtx.m_mtsTxnBranch.BranchNumber];
											}
											if (val != null && val.m_endUserSessionId == pr.m_endUserSessionId && val.m_endUserSerialNum == pr.m_endUserSerialNum)
											{
												if (ProviderConfig.m_bTraceLevelPrivate)
												{
													Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.Put, Trace.GetCPInfo(pr as OracleConnectionImpl, null, null, "disp:put:nul1", bResourcePoolInfo: true));
												}
												pr.m_txnCtx.m_enlistedPRList[pr.m_mtsTxnCtx.m_mtsTxnBranch.BranchNumber] = null;
											}
											else if (ProviderConfig.m_bTraceLevelPrivate)
											{
												Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.Put, Trace.GetCPInfo(pr as OracleConnectionImpl, null, null, "disp:put:didnotnullyafterdelist", bResourcePoolInfo: true));
											}
										}
									}
									if (pr.m_mtsTxnCtx != null)
									{
										pr.m_mtsTxnCtx.m_mtsTxnBranch = null;
									}
									pr.m_txnCtx = null;
									pr.m_pm.Put(pr, connRefForCriteria);
								}
								else if (pr.m_txnCtx != null && pr.m_mtsTxnCtx != null && pr.m_mtsTxnCtx.m_txnType != 0 && pr.m_mtsTxnCtx.m_mtsTxnBranch != null && pr.m_localTxnId == pr.m_txnCtx.m_localTxnId && pr.m_txnCtx.m_enlistedPRList[pr.m_mtsTxnCtx.m_mtsTxnBranch.BranchNumber] == null)
								{
									lock (pr.m_txnCtx)
									{
										if (pr.m_mtsTxnCtx != null && pr.m_mtsTxnCtx.m_txnType != 0 && pr.m_mtsTxnCtx.m_mtsTxnBranch != null && pr.m_localTxnId == pr.m_txnCtx.m_localTxnId && pr.m_txnCtx.m_enlistedPRList[pr.m_mtsTxnCtx.m_mtsTxnBranch.BranchNumber] == null)
										{
											pr.m_txnCtx.m_enlistedPRList[pr.m_mtsTxnCtx.m_mtsTxnBranch.BranchNumber] = pr;
											if (pr.m_mtsTxnCtx.m_mtsTxnBranch.BranchNumber != 0 && !pr.m_txnCtx.m_instances.Contains(pr.m_instanceName))
											{
												pr.m_txnCtx.m_instances.Add(pr.m_instanceName);
												pr.m_bTxnCtxPrimaryCon = true;
											}
											if (pr.m_mtsTxnCtx.m_mtsTxnBranch.BranchNumber > pr.m_txnCtx.m_maxBranchIndex)
											{
												pr.m_txnCtx.m_maxBranchIndex = pr.m_mtsTxnCtx.m_mtsTxnBranch.BranchNumber;
											}
											if (ProviderConfig.m_bTraceLevelPrivate)
											{
												Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.Put, Trace.GetCPInfo(pr as OracleConnectionImpl, null, null, "disp:put:res1", bResourcePoolInfo: true));
											}
										}
									}
								}
							}
						}
					}
					if (pr.m_bPutCompleted || pr.m_mtsTxnCtx.m_txnType != 0 || pr.m_bTxnCtxPrimaryCon)
					{
						return;
					}
					lock (pr)
					{
						if (!pr.m_bPutCompleted && pr.m_mtsTxnCtx.m_txnType == MTSTxnType.None && !pr.m_bTxnCtxPrimaryCon && pr.m_txnCtx != null && pr.m_mtsTxnCtx != null && pr.m_mtsTxnCtx.m_mtsTxnBranch != null && pr.m_localTxnId == pr.m_txnCtx.m_localTxnId)
						{
							lock (pr.m_txnCtx)
							{
								if (pr.m_mtsTxnCtx != null && pr.m_mtsTxnCtx.m_mtsTxnBranch != null && pr.m_localTxnId == pr.m_txnCtx.m_localTxnId && pr.m_mtsTxnCtx.m_txnType == MTSTxnType.None)
								{
									PR val2 = null;
									if (pr.m_mtsTxnCtx.m_mtsTxnBranch != null)
									{
										val2 = pr.m_txnCtx.m_enlistedPRList[pr.m_mtsTxnCtx.m_mtsTxnBranch.BranchNumber];
									}
									if (val2 != null && val2.m_endUserSessionId == pr.m_endUserSessionId && val2.m_endUserSerialNum == pr.m_endUserSerialNum)
									{
										if (ProviderConfig.m_bTraceLevelPrivate)
										{
											Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.Put, Trace.GetCPInfo(pr as OracleConnectionImpl, null, null, "disp:put:null1", bResourcePoolInfo: true));
										}
										pr.m_txnCtx.m_enlistedPRList[pr.m_mtsTxnCtx.m_mtsTxnBranch.BranchNumber] = null;
									}
								}
							}
						}
						if (!pr.m_bCheckedOutByApp && !pr.m_bPutCompleted && !pr.m_bCheckedOutByDTC && !pr.m_bTxnCtxPrimaryCon)
						{
							if (pr.m_mtsTxnCtx != null)
							{
								pr.m_mtsTxnCtx.m_mtsTxnBranch = null;
							}
							pr.m_txnCtx = null;
							pr.m_pm.Put(pr, connRefForCriteria);
						}
					}
					return;
				}
				if (pr.m_bCheckedOutByApp || pr.m_bPutCompleted || pr.m_bCheckedOutByDTC)
				{
					return;
				}
				lock (pr)
				{
					if (pr.m_bCheckedOutByApp || pr.m_bPutCompleted || pr.m_bCheckedOutByDTC)
					{
						return;
					}
					if (pr.m_txnCtx != null && pr.m_mtsTxnCtx != null && pr.m_mtsTxnCtx.m_mtsTxnBranch != null && pr.m_localTxnId == pr.m_txnCtx.m_localTxnId && pr.m_mtsTxnCtx.m_txnType == MTSTxnType.None)
					{
						lock (pr.m_txnCtx)
						{
							if (pr.m_mtsTxnCtx != null && pr.m_mtsTxnCtx.m_mtsTxnBranch != null && pr.m_localTxnId == pr.m_txnCtx.m_localTxnId && pr.m_mtsTxnCtx.m_txnType == MTSTxnType.None)
							{
								PR val3 = null;
								if (pr.m_mtsTxnCtx.m_mtsTxnBranch != null)
								{
									val3 = pr.m_txnCtx.m_enlistedPRList[pr.m_mtsTxnCtx.m_mtsTxnBranch.BranchNumber];
								}
								if (val3 != null && val3.m_endUserSessionId == pr.m_endUserSessionId && val3.m_endUserSerialNum == pr.m_endUserSerialNum)
								{
									if (ProviderConfig.m_bTraceLevelPrivate)
									{
										Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.Put, Trace.GetCPInfo(pr as OracleConnectionImpl, null, null, "disp:put:nul2", bResourcePoolInfo: true));
									}
									pr.m_txnCtx.m_enlistedPRList[pr.m_mtsTxnCtx.m_mtsTxnBranch.BranchNumber] = null;
								}
							}
						}
					}
					pr.m_txnCtx = null;
					pr.m_pm.Put(pr, connRefForCriteria);
				}
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268437504, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.Put, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2560, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.Put, Trace.GetCPInfo(pr as OracleConnectionImpl, null, null, null));
				}
			}
		}

		internal static void ClearAllPools()
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.ClearAllPools);
			}
			try
			{
				List<PM> list = m_listPM.GetList();
				for (int i = 0; i < list.Count; i++)
				{
					list[i].ClearAllPools(null);
				}
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268437504, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.ClearAllPools, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2560, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.ClearAllPools);
				}
			}
		}

		internal static void ClearPool(ConnectionString cs)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.ClearPool);
			}
			try
			{
				if (cs.m_conPoolKey != null)
				{
					m_htPM[cs.m_conPoolKey]?.ClearAllPools(null);
				}
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268437504, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.ClearPool, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2560, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.ClearPool);
				}
			}
		}

		internal static List<string> GetDataSources()
		{
			return m_listDataSources.GetList();
		}

		internal static List<PM> GetImpactedShardingPMs(OracleChunkEventArgs chunkEvent)
		{
			List<PM> list = m_listPM.GetList();
			List<PM> list2 = new List<PM>();
			foreach (PM item in list)
			{
				if (string.Compare(item.m_databaseDomainName, chunkEvent.DatabaseDomain, ignoreCase: true) == 0 && string.Compare(item.m_databaseName, chunkEvent.Database, ignoreCase: true) == 0)
				{
					list2.Add(item);
				}
			}
			return list2;
		}

		internal static void ProcessChunkMoveEvent(OracleChunkEventArgs chunkEvent)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.ProcessChunkMoveEvent);
			}
			lock (s_shardLockObj)
			{
				if (chunkEvent.Status == OracleChunkEventStatus.Add)
				{
					if (ProviderConfig.m_bTraceLevelPrivate)
					{
						Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.ProcessChunkMoveEvent, $"Sharding:Add for {chunkEvent.DatabaseDomain}|{chunkEvent.Database}|{chunkEvent.Instance}|{chunkEvent.Chunk}");
					}
					List<ShardRoutingCache> sharedShardRoutingCaches = PoolManager<PM, CP, PR>.GetSharedShardRoutingCaches(chunkEvent.Database);
					if (sharedShardRoutingCaches != null)
					{
						foreach (ShardRoutingCache item in sharedShardRoutingCaches)
						{
							item.OnAddChunk(chunkEvent);
						}
					}
				}
				else if (chunkEvent.Status == OracleChunkEventStatus.AddValues)
				{
					if (ProviderConfig.m_bTraceLevelPrivate)
					{
						Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.ProcessChunkMoveEvent, $"Sharding:AddValues for {chunkEvent.DatabaseDomain}|{chunkEvent.Database}|{chunkEvent.Instance}|{chunkEvent.Chunk}");
					}
					List<ShardRoutingCache> sharedShardRoutingCaches2 = PoolManager<PM, CP, PR>.GetSharedShardRoutingCaches(chunkEvent.Database);
					if (sharedShardRoutingCaches2 != null)
					{
						foreach (ShardRoutingCache item2 in sharedShardRoutingCaches2)
						{
							item2.OnAddChunkValues(chunkEvent);
						}
					}
				}
				else if (chunkEvent.Status == OracleChunkEventStatus.Drop)
				{
					if (ProviderConfig.m_bTraceLevelPrivate)
					{
						Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.ProcessChunkMoveEvent, $"Sharding:Drop for {chunkEvent.DatabaseDomain}|{chunkEvent.Database}|{chunkEvent.Instance}|{chunkEvent.Chunk}");
					}
					List<ShardRoutingCache> sharedShardRoutingCaches3 = PoolManager<PM, CP, PR>.GetSharedShardRoutingCaches(chunkEvent.Database);
					if (sharedShardRoutingCaches3 != null)
					{
						foreach (ShardRoutingCache item3 in sharedShardRoutingCaches3)
						{
							item3.OnDropChunk(chunkEvent);
						}
					}
				}
				else if (chunkEvent.Status == OracleChunkEventStatus.DropValues)
				{
					if (ProviderConfig.m_bTraceLevelPrivate)
					{
						Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.ProcessChunkMoveEvent, $"Sharding:DropValues for {chunkEvent.DatabaseDomain}|{chunkEvent.Database}|{chunkEvent.Instance}|{chunkEvent.Chunk}");
					}
					List<ShardRoutingCache> sharedShardRoutingCaches4 = PoolManager<PM, CP, PR>.GetSharedShardRoutingCaches(chunkEvent.Database);
					if (sharedShardRoutingCaches4 != null)
					{
						foreach (ShardRoutingCache item4 in sharedShardRoutingCaches4)
						{
							item4.OnDropChunkValues(chunkEvent);
						}
					}
				}
				else if (chunkEvent.Status == OracleChunkEventStatus.Merge)
				{
					if (ProviderConfig.m_bTraceLevelPrivate)
					{
						Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.ProcessChunkMoveEvent, $"Sharding:Merge for {chunkEvent.DatabaseDomain}|{chunkEvent.Database}|{chunkEvent.Instance}|{chunkEvent.Chunk}");
					}
					List<ShardRoutingCache> sharedShardRoutingCaches5 = PoolManager<PM, CP, PR>.GetSharedShardRoutingCaches(chunkEvent.Database);
					if (sharedShardRoutingCaches5 != null)
					{
						foreach (ShardRoutingCache item5 in sharedShardRoutingCaches5)
						{
							item5.OnMergeChunk(chunkEvent);
						}
					}
				}
				else if (chunkEvent.Status == OracleChunkEventStatus.Invalidate)
				{
					if (ProviderConfig.m_bTraceLevelPrivate)
					{
						Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.ProcessChunkMoveEvent, $"Sharding:Invalidate for {chunkEvent.DatabaseDomain}|{chunkEvent.Database}|{chunkEvent.Instance}|{chunkEvent.Chunk}");
					}
					List<ShardRoutingCache> sharedShardRoutingCaches6 = PoolManager<PM, CP, PR>.GetSharedShardRoutingCaches(chunkEvent.Database);
					if (sharedShardRoutingCaches6 != null)
					{
						foreach (ShardRoutingCache item6 in sharedShardRoutingCaches6)
						{
							item6.OnInvalidateChunk(chunkEvent);
						}
					}
				}
				else if (chunkEvent.Status == OracleChunkEventStatus.ReadOnly)
				{
					if (ProviderConfig.m_bTraceLevelPrivate)
					{
						Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.ProcessChunkMoveEvent, $"Sharding:ReadOnly:CreateEvent for {chunkEvent.DatabaseDomain}|{chunkEvent.Database}|{chunkEvent.Instance}|{chunkEvent.Chunk}");
					}
					m_sChunkUpEvents.CreateEvent(chunkEvent.Database, chunkEvent.Instance, chunkEvent.Chunk);
					List<ShardRoutingCache> sharedShardRoutingCaches7 = PoolManager<PM, CP, PR>.GetSharedShardRoutingCaches(chunkEvent.Database);
					if (sharedShardRoutingCaches7 != null)
					{
						foreach (ShardRoutingCache item7 in sharedShardRoutingCaches7)
						{
							item7.OnMigrateChunk(chunkEvent);
						}
					}
				}
				else if (chunkEvent.Status == OracleChunkEventStatus.Up)
				{
					if (ProviderConfig.m_bTraceLevelPrivate)
					{
						Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.ProcessChunkMoveEvent, $"Sharding:Up:SetAndRemoveEvent for {chunkEvent.DatabaseDomain}|{chunkEvent.Database}|{chunkEvent.Instance}|{chunkEvent.Chunk}");
					}
					List<ShardRoutingCache> sharedShardRoutingCaches8 = PoolManager<PM, CP, PR>.GetSharedShardRoutingCaches(chunkEvent.Database);
					if (sharedShardRoutingCaches8 != null)
					{
						foreach (ShardRoutingCache item8 in sharedShardRoutingCaches8)
						{
							item8.OnMigrateChunk(chunkEvent);
						}
					}
					m_sChunkUpEvents.SetAndRemoveEvent(chunkEvent.Database, chunkEvent.Instance, chunkEvent.Chunk);
				}
				else if (chunkEvent.Status == OracleChunkEventStatus.Down)
				{
					if (ProviderConfig.m_bTraceLevelPrivate)
					{
						Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.ProcessChunkMoveEvent, $"Sharding:Down for {chunkEvent.DatabaseDomain}|{chunkEvent.Database}|{chunkEvent.Instance}|{chunkEvent.Chunk}");
					}
					List<ShardRoutingCache> sharedShardRoutingCaches9 = PoolManager<PM, CP, PR>.GetSharedShardRoutingCaches(chunkEvent.Database);
					if (sharedShardRoutingCaches9 != null)
					{
						foreach (ShardRoutingCache item9 in sharedShardRoutingCaches9)
						{
							item9.OnRemoveChunk(chunkEvent);
						}
					}
					m_sChunkUpEvents.SetAndRemoveEvent(chunkEvent.Database, chunkEvent.Instance, chunkEvent.Chunk);
				}
				else if (chunkEvent.Status == OracleChunkEventStatus.Split)
				{
					if (ProviderConfig.m_bTraceLevelPrivate)
					{
						Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.ProcessChunkMoveEvent, $"Sharding:Split for {chunkEvent.DatabaseDomain}|{chunkEvent.Database}|{chunkEvent.Instance}|{chunkEvent.Chunk}");
					}
					List<ShardRoutingCache> sharedShardRoutingCaches10 = PoolManager<PM, CP, PR>.GetSharedShardRoutingCaches(chunkEvent.Database);
					if (sharedShardRoutingCaches10 != null)
					{
						foreach (ShardRoutingCache item10 in sharedShardRoutingCaches10)
						{
							item10.OnSplitChunk(chunkEvent);
						}
					}
				}
			}
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2560, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.ProcessChunkMoveEvent);
			}
		}

		internal static void ProcessHAEvent(OracleHAEventArgs haEvent)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.ProcessHAEvent);
			}
			string text = string.Empty;
			bool flag = true;
			try
			{
				if (haEvent.m_bFireHADotNetEvent)
				{
					ThreadPool.QueueUserWorkItem(new WaitCallback(OracleConnection.OnHAEvent), haEvent);
				}
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					string str = "haEvent.DatabaseName      : " + haEvent.DatabaseName + " \n";
					str = str + "haEvent.ServiceName       : " + haEvent.ServiceName + " \n";
					str = str + "haEvent.InstanceName      : " + haEvent.InstanceName + " \n";
					str = str + "haEvent.Source            : " + haEvent.Source.ToString() + " \n";
					str = str + "haEvent.HostName          : " + haEvent.HostName + " \n";
					str = str + "haEvent.Reason            : " + haEvent.Reason + " \n";
					str = str + "haEvent.Status            : " + haEvent.Status.ToString() + " \n";
					str = str + "haEvent.Time              : " + haEvent.Time.ToString() + " \n";
					str = str + "haEvent.DatabaseDomainName: " + haEvent.DatabaseDomainName + " \n";
					str = str + "haEvent.drain_timeout   : " + haEvent.DrainTimeout + " \n";
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.ProcessHAEvent, "ProcessHAEvent Info: \n" + str);
				}
				if (haEvent.Status == OracleHAEventStatus.Down)
				{
					if (!string.IsNullOrEmpty(haEvent.Reason))
					{
						text = haEvent.Reason.Trim().ToLowerInvariant();
					}
					if (text.ToLower() == "user" || text.ToLower() == "user_action" || text.ToLower() == "application_state_change")
					{
						flag = false;
					}
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.ProcessHAEvent, "HA Event Type : " + (flag ? "(UNPLANNED OUTAGE)" : "(PLANNED OUTAGE)"));
					switch (haEvent.Source)
					{
					case OracleHAEventSource.Database:
					case OracleHAEventSource.Service:
					{
						List<PM> list = m_listPM.GetList();
						List<CP> list3 = new List<CP>();
						List<PM> list4 = new List<PM>();
						for (int k = 0; k < list.Count; k++)
						{
							PM val3 = list[k];
							if (val3 != null && !val3.m_bHAEnabled)
							{
								continue;
							}
							val3.m_drain_timeout = haEvent.DrainTimeout;
							string text2 = haEvent.ServiceName.ToLowerInvariant();
							string a = haEvent.DatabaseName.ToLowerInvariant();
							Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.ProcessHAEvent, string.Format("Service {0} present in SvcCtx: {1}, SvcCtx.DatabaseName: {2}, PM.ID: {3}", text2, val3.m_dictSvcCtx.ContainsKey(text2).ToString(), val3.m_dictSvcCtx.ContainsKey(text2) ? val3.m_dictSvcCtx[text2].m_databaseName : "null", val3.m_id));
							if ((haEvent.DatabaseDomainName != null && haEvent.DatabaseDomainName.Length != 0 && (val3.m_databaseDomainName == null || !(val3.m_databaseDomainName.ToLowerInvariant() == haEvent.DatabaseDomainName.ToLowerInvariant()))) || !val3.m_dictSvcCtx.ContainsKey(text2) || !(a == val3.m_dictSvcCtx[text2].m_databaseName.ToLowerInvariant()))
							{
								continue;
							}
							val3.m_dictSvcCtx[text2].UpdateServiceDown(isServiceDown: true, haEvent.Time);
							if (val3.m_dictDictCP[haEvent.ServiceName] != null)
							{
								foreach (CP value in val3.m_dictDictCP[haEvent.ServiceName].GetValues())
								{
									value.MarkAllPRsForDeletion(haEvent.Time, flag);
									list3.Add(value);
								}
							}
							RLBManager.InvalidateRLBData((haEvent.DatabaseName + "|" + haEvent.ServiceName).ToLowerInvariant());
							if (!flag)
							{
								if (ProviderConfig.m_bTraceLevelPrivate)
								{
									Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.ProcessHAEvent, $"Service DOWN for service: {haEvent.ServiceName}");
								}
								val3.m_dictSvcCtx[text2].m_serviceDownTime = DateTime.Now;
								if (ProviderConfig.m_bTraceLevelPrivate)
								{
									Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.ProcessHAEvent, "ServiceUpEvent RESET for connection pool " + val3.GetHashCode());
								}
								val3.m_dictSvcCtx[text2].m_serviceUpEvent.Reset();
								val3.m_dictSvcCtx[text2].m_bWaitedForSvcReloc = false;
							}
							if (val3.m_dictSvcCtx.Count == 1)
							{
								list4.Add(val3);
							}
						}
						for (int l = 1; l <= 2; l++)
						{
							foreach (CP item in list3)
							{
								item.ClearPool(null, flag);
							}
							foreach (PM item2 in list4)
							{
								item2.ClearAllPools(null, flag);
							}
							if (l == 1)
							{
								Thread.Sleep(3000);
							}
						}
						break;
					}
					case OracleHAEventSource.Instance:
					case OracleHAEventSource.ServiceMember:
					{
						List<PM> list = m_listPM.GetList();
						List<CP> list3 = new List<CP>();
						for (int m = 0; m < list.Count; m++)
						{
							PM val4 = list[m];
							Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.ProcessHAEvent, string.Format("Service {0} present in SvcCtx: {1}, SvcCtx.DatabaseName: {2}, currentPM.ID: {3}, currentPM.DatabaseDomainName: {4}", haEvent.ServiceName, val4.m_dictSvcCtx.ContainsKey(haEvent.ServiceName), val4.m_dictSvcCtx.ContainsKey(haEvent.ServiceName) ? val4.m_dictSvcCtx[haEvent.ServiceName].m_databaseName : "null", val4.m_id, val4.m_databaseDomainName));
							if (val4 != null && !val4.m_bHAEnabled)
							{
								continue;
							}
							val4.m_drain_timeout = haEvent.DrainTimeout;
							if ((haEvent.DatabaseDomainName == null || haEvent.DatabaseDomainName.Length == 0 || (val4.m_databaseDomainName != null && val4.m_databaseDomainName.ToLowerInvariant() == haEvent.DatabaseDomainName.ToLowerInvariant())) && val4.m_dictSvcCtx.ContainsKey(haEvent.ServiceName) && val4.m_dictDictCP[haEvent.ServiceName] != null && val4.m_dictDictCP[haEvent.ServiceName].Count > 0 && val4.m_dictSvcCtx[haEvent.ServiceName].m_databaseName.ToLowerInvariant() == haEvent.DatabaseName.ToLowerInvariant())
							{
								if (ProviderConfig.m_bTraceLevelPrivate)
								{
									Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.ProcessHAEvent, $"ServiceMember DOWN for service: {haEvent.ServiceName}, instance name: {haEvent.InstanceName}");
								}
								val4.m_dictSvcCtx[haEvent.ServiceName].CheckAndUpdateServiceMemberDOWNNames_HA(haEvent.InstanceName, serviceMemberDown: true, haEvent.Time);
								CP val5 = null;
								if (val4.m_dictDictCP[haEvent.ServiceName] != null && val4.m_dictDictCP[haEvent.ServiceName].ContainsKey(haEvent.InstanceName))
								{
									val5 = val4.m_dictDictCP[haEvent.ServiceName][haEvent.InstanceName];
								}
								if (val5 != null)
								{
									val5.MarkAllPRsForDeletion(haEvent.Time, flag);
									RLBManager.InvalidateRLBData((haEvent.DatabaseName + "|" + haEvent.ServiceName).ToLowerInvariant());
									list3.Add(val5);
								}
							}
						}
						for (int n = 1; n <= 2; n++)
						{
							foreach (CP item3 in list3)
							{
								item3.ClearPool(null, flag);
							}
							if (n == 1)
							{
								Thread.Sleep(3000);
							}
						}
						break;
					}
					case OracleHAEventSource.Node:
					{
						List<PM> list = m_listPM.GetList();
						bool flag2 = false;
						for (int i = 0; i < list.Count; i++)
						{
							flag2 = false;
							PM val = list[i];
							if (val != null && !val.m_bHAEnabled)
							{
								continue;
							}
							List<PR> list2 = val.m_pmListPR.GetList();
							for (int j = 0; j < list2.Count; j++)
							{
								PR val2 = list2[j];
								if (!(val2.m_hostName == haEvent.HostName))
								{
									continue;
								}
								lock (val2)
								{
									if (ProviderConfig.m_bTraceLevelPrivate)
									{
										string str2 = $"({val2.m_endUserSessionId}:{val2.m_endUserSerialNum})";
										Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.ProcessHAEvent, str2 + " : (HA) Setting pr.m_deletionRequestor = DeletionRequestor.HA");
									}
									val2.m_deletionRequestor = DeletionRequestor.HA;
									val2.m_pm.Close(val2, null);
								}
								flag2 = true;
							}
							if (flag2)
							{
								RLBManager.InvalidateRLBData((haEvent.DatabaseName + "|" + haEvent.ServiceName).ToLowerInvariant());
							}
						}
						break;
					}
					}
					return;
				}
				if (!string.IsNullOrEmpty(haEvent.Reason))
				{
					text = haEvent.Reason.Trim().ToLowerInvariant();
				}
				if (text.ToLower() == "user" || text.ToLower() == "user_action" || text.ToLower() == "application_state_change")
				{
					flag = false;
				}
				Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.ProcessHAEvent, "HA Event Type : " + (flag ? "(UNPLANNED OUTAGE)" : "(PLANNED OUTAGE)"));
				List<PM> list5 = null;
				switch (haEvent.Source)
				{
				case OracleHAEventSource.Database:
				case OracleHAEventSource.Service:
				{
					list5 = m_listPM.GetList();
					for (int num3 = 0; num3 < list5.Count; num3++)
					{
						PM val9 = list5[num3];
						if ((val9 != null && !val9.m_bHAEnabled) || haEvent.ServiceName == null || !val9.m_dictSvcCtx.ContainsKey(haEvent.ServiceName))
						{
							continue;
						}
						if (OracleHAEventSource.Service == haEvent.Source)
						{
							if (ProviderConfig.m_bTraceLevelPrivate)
							{
								Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.ProcessHAEvent, $"Service UP for service: {haEvent.ServiceName}, currentPM.ID: {val9.m_id}");
							}
							val9.m_dictSvcCtx[haEvent.ServiceName].UpdateServiceDown(isServiceDown: false, haEvent.Time);
							val9.m_dictSvcCtx[haEvent.ServiceName].m_serviceUpEvent.Set();
							val9.m_dictSvcCtx[haEvent.ServiceName].m_bWaitedForSvcReloc = false;
							if (ProviderConfig.m_bTraceLevelPrivate)
							{
								Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.ProcessHAEvent, "ServiceUp: ServiceUpEvent SET for connection pool " + val9.GetHashCode());
							}
						}
						else
						{
							val9.m_dictSvcCtx[haEvent.ServiceName].m_databaseName = haEvent.DatabaseName;
							if (ProviderConfig.m_bTraceLevelPrivate)
							{
								Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.ProcessHAEvent, $"Database UP for service: {haEvent.ServiceName}, currentPM.ID: {val9.m_id}, Update Database Name to:{haEvent.DatabaseName}");
							}
						}
					}
					break;
				}
				case OracleHAEventSource.Instance:
				case OracleHAEventSource.ServiceMember:
				{
					list5 = m_listPM.GetList();
					for (int num = 0; num < list5.Count; num++)
					{
						PM val6 = list5[num];
						if ((val6 != null && !val6.m_bHAEnabled) || (haEvent.DatabaseDomainName != null && haEvent.DatabaseDomainName.Length != 0 && (val6.m_databaseDomainName == null || !(val6.m_databaseDomainName.ToLowerInvariant() == haEvent.DatabaseDomainName.ToLowerInvariant()))) || !val6.m_dictSvcCtx.ContainsKey(haEvent.ServiceName) || val6.m_dictDictCP[haEvent.ServiceName] == null || val6.m_dictDictCP[haEvent.ServiceName].Count <= 0)
						{
							continue;
						}
						if (ProviderConfig.m_bTraceLevelPrivate)
						{
							Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.ProcessHAEvent, $"ServiceMember UP for service: {haEvent.ServiceName}, instance name: {haEvent.InstanceName}, currentPM.ID: {val6.m_id}");
						}
						val6.m_dictSvcCtx[haEvent.ServiceName].m_databaseName = haEvent.DatabaseName;
						val6.m_dictSvcCtx[haEvent.ServiceName].CheckAndUpdateServiceMemberDOWNNames_HA(haEvent.InstanceName, serviceMemberDown: false, haEvent.Time);
						val6.m_dictSvcCtx[haEvent.ServiceName].UpdateServiceDown(isServiceDown: false, haEvent.Time);
						CP val7 = null;
						if (val6.m_dictDictCP[haEvent.ServiceName] != null && val6.m_dictDictCP[haEvent.ServiceName].ContainsKey(haEvent.InstanceName))
						{
							val7 = val6.m_dictDictCP[haEvent.ServiceName][haEvent.InstanceName];
						}
						if (val7 == null)
						{
							continue;
						}
						SyncQueueList<PR> cpListPR = val7.m_cpListPR;
						for (int num2 = 0; num2 < cpListPR.Count; num2++)
						{
							try
							{
								PR val8 = cpListPR[num2];
								if (val8 == null)
								{
									continue;
								}
								lock (val8)
								{
									if (flag && !val8.IsTAFEnabled())
									{
										val8.m_deletionRequestor = DeletionRequestor.HA;
									}
								}
							}
							catch
							{
							}
						}
						bool flag3 = false;
						if (val7.m_bInstanceDown && haEvent.Time > val7.m_lastHADownEventUtcDateTime)
						{
							flag3 = true;
							val7.m_bInstanceDown = false;
							if (OracleHAEventSource.ServiceMember == haEvent.Source)
							{
								val6.m_dictSvcCtx[haEvent.ServiceName].m_serviceUpEvent.Set();
								val6.m_dictSvcCtx[haEvent.ServiceName].m_bWaitedForSvcReloc = false;
								if (ProviderConfig.m_bTraceLevelPrivate)
								{
									Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.ProcessHAEvent, "ServiceMemberUp: ServiceUpEvent SET for connection pool " + val6.GetHashCode());
								}
							}
						}
						if (ProviderConfig.m_bTraceLevelPrivate)
						{
							string text3 = $"[pm_id={val6.m_id}][instance={val7.m_instanceName}][instance_down={val7.m_bInstanceDown}][type=ha_up_event][state_changed={flag3}][up_event_utc={haEvent.Time.ToString()}][last_down_event_utc={val7.m_lastHADownEventUtcDateTime.ToString()}]";
							Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.ProcessHAEvent, text3);
						}
					}
					break;
				}
				case OracleHAEventSource.Node:
					break;
				}
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268437504, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.ProcessHAEvent, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2560, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.ProcessHAEvent);
				}
			}
		}

		internal static PR GetEnlisted(ConnectionString cs, OracleConnection con, string serviceName, string pdbName, Transaction txn, string affinityInstance, int branchNum, bool bMustMatch, out bool bMatchFound)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.GetEnlisted, Trace.GetCPInfo(null, txn, null, null) + "Disp.GetEnlisted(br={0};must={1})", branchNum.ToString(), bMustMatch.ToString());
			}
			bMatchFound = false;
			PR val = null;
			try
			{
				_ = cs.m_pmId;
				PM val2 = null;
				bool newPM = false;
				bool bAuthenticated = false;
				val2 = GetPM(cs, con, cs.m_pm as PM, null, null, null, out bAuthenticated, out newPM);
				val = val2.GetEnlisted(txn, affinityInstance, branchNum, bMustMatch, out bMatchFound, serviceName, pdbName);
				if (val == null && bMustMatch)
				{
					return val;
				}
				if (val == null)
				{
					OracleConnection oracleConnection = new OracleConnection();
					oracleConnection.m_serviceName = serviceName;
					oracleConnection.m_pdbName = pdbName;
					oracleConnection.m_fromMTS = true;
					val = val2.Get(cs, bGetForApp: false, oracleConnection, affinityInstance);
					if (val != null)
					{
						val.m_resPoolRefCount++;
					}
				}
				return val;
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268437504, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.GetEnlisted, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2560, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.GetEnlisted, Trace.GetCPInfo(val as OracleConnectionImpl, txn, null, null) + "Disp.GetEnlisted(br={0};must={1}) return (matchfound={2})", branchNum.ToString(), bMustMatch.ToString().Substring(0, 1), bMatchFound.ToString().Substring(0, 1));
				}
			}
		}

		internal static MTSTxnRM GetRM(ConnectionString cs, OracleConnection connRefForCriteria, Transaction txn, OracleConnectionImpl pr)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.GetRM);
			}
			try
			{
				bool bAuthenticated = false;
				bool newPM = false;
				return GetPM(cs, null, cs.m_pm as PM, null, null, null, out bAuthenticated, out newPM).GetRM(txn, connRefForCriteria, pr as PR);
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268437504, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.GetRM, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2560, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.GetRM, Trace.GetCPInfo(pr, null, null, null));
				}
			}
		}

		internal static void RemoveRM(ConnectionString cs, string serviceName, Transaction txn)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.RemoveRM, Trace.GetCPInfo(null, txn, null, null));
			}
			PM val = null;
			try
			{
				bool bAuthenticated = false;
				bool newPM = false;
				GetPM(cs, null, cs.m_pm as PM, null, null, null, out bAuthenticated, out newPM)?.RemoveRM(serviceName, txn);
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268437504, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.RemoveRM, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2560, OracleTraceClassName.OracleConnectionDispenser, OracleTraceFuncName.RemoveRM, Trace.GetCPInfo(null, txn, null, null));
				}
			}
		}
	}
}
